import useEaseInOut from '@/hooks/easeInOut'
import {ECOption} from '@/libs/global/echarts'
import deepClone from '@/libs/deepClone'
import {coustomEchartTooltip} from '@/libs/toolkit'
import {PropType} from 'vue'
import CEcharts from './echarts'

const WaterTarget = defineComponent({
  props: {
    id: {
      type: String,
      required: true
    },
    showDashed: {
      type: Boolean,
      default: true
    },
    radius: {
      type: Number,
      default: 61
    },
    borderColor: {
      type: [String, Array] as PropType<string | string[]>,
      default: '#3A85FF'
    },
    borderWidth: {
      type: Number,
      default: 8
    },
    lightborderColor: {
      type: [String, Array] as PropType<string | string[]>,
      default: '#D6E9FF'
    },
    dashWidth: {
      type: Number,
      default: 4
    },
    fontSize: {
      type: Number,
      default: 36
    },
    fontColor: {
      type: String,
      default: '#3A85FF'
    },
    range: {
      type: Number,
      required: true
    },
    tooltipTitle: String,
    scaleColor: {type: String, default: '#1f87ff2b'}
  },
  setup(this, props, {slots}) {
    const state = reactive<{[key: string]: any}>({
      ctx: null,
      circleX: null,
      circleY: null,
      angle: 0
    })

    /**
     * 画圆环
     * @param r {number} 圆环的半径
     * @param w {number} 圆环的宽度
     * @param c {string} 圆环的颜色
     * @param angle {string} 圆环所到的角度 默认180度，半圆
     */
    const circle = (r: any, w: any, c: string | string[], angle: any = 180) => {
      const ctx = state.ctx
      // 画布将当前的状态保存
      // canvas.save();与canvas.restore();一般结合使用，.save()函数在前，.restore()函数在后，
      // 用来保证在这两个函数之间所做的操作不会对原来在canvas上所画图形产生影响
      ctx.save()
      // 开始一条路径，或重置当前的路径
      ctx.beginPath()
      // 设置线条的宽度
      ctx.lineWidth = w

      if (Array.isArray(c)) {
        const con = r * 2
        const grd = ctx.createLinearGradient(con, con, con, 0)
        grd.addColorStop(0, c[1])
        grd.addColorStop(1, c[0])
        // 设置线条的颜色
        ctx.strokeStyle = grd
      } else {
        ctx.strokeStyle = c
      }

      // 线条末端线帽的设置为圆形
      ctx.lineCap = 'round'
      // 方法创建弧/曲线（用于创建圆或部分圆）
      ctx.arc(state.circleX, state.circleY, r, Math.PI, Math.PI * (1 + angle / 180))
      ctx.stroke()
      // 画布取出原来所保存的状态
      ctx.restore()
    }
    /**
     * 绘制刻度线
     * @param s {number}  弧度所对应的角度
     * @param span {number}  弧度间隔
     * @param sl {number}  刻度线以圆心为半径的起始半径
     * @param el {number}  刻度线以圆心为半径的结束半径
     * @param c {string}  刻度线的颜色
     */
    const scale = (s: any, span: any, sl: any, el: any, c: any) => {
      const ctx = state.ctx
      let startA = s
      const width = ctx.canvas.width
      const height = ctx.canvas.height
      for (let i = 0; i < span; i++) {
        ctx.save()
        ctx.beginPath()
        const rad = (startA * 15 * Math.PI) / 180
        const startX = width / 2 - Math.cos(rad) * sl
        const startY = height / 2 - Math.sin(rad) * sl
        const endX = width / 2 - Math.cos(rad) * el
        const endY = height / 2 - Math.sin(rad) * el
        // 路径移动到画布中的指定点，不创建线条
        ctx.moveTo(startX, startY)
        // 添加一个新点，然后创建从该点到画布中最后指定点的线条（该方法并不会创建线条）
        ctx.lineTo(endX, endY)
        ctx.strokeStyle = c
        // 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
        ctx.stroke()
        ctx.restore()
        startA++
      }
    }

    /**
     * 绘制文字
     * @param text {string}  文字的内容
     * @param x {number}  文字的x坐标轴
     * @param y {number}  文字的y坐标轴
     * @param c {string}  刻度线的颜色
     * @param fontSize {number}  字体大小
     */
    // const fillText = (text: any, x: any, y: any, color: any = '#333', fontSize: any = '18') => {
    //   const ctx = state.ctx
    //   ctx.save()
    //   // 根据锚点，设置或返回文本内容的当前对齐方式    水平方向
    //   ctx.textAlign = 'center'
    //   // 设置或返回在绘制文本时的当前文本基线    垂直方向
    //   ctx.textBaseline = 'middle'
    //   // console.log(x, y, ctx.measureText(text).width, fontSize / 2);
    //   // 设置或返回画布上文本内容的当前字体属性
    //   ctx.font = fontSize + 'px Arial'
    //   ctx.fillStyle = color

    //   // 在画布上绘制填色的文本
    //   ctx.fillText(text, x, y)
    //   ctx.restore()
    // }

    /**
     * 绘制圆
     * @param x {number} 圆心的x坐标轴
     * @param y {number} 圆心的y坐标轴
     * @param r {number} 圆的半径
     * @param fillColor {string} 圆所填充的颜色
     * @param lineWidth {number} 圆的宽度
     */
    // const round = (x: any, y: any, r: any, fillColor: any = '#fff', lineWidth: any = 3) => {
    //   const ctx = state.ctx
    //   ctx.save()
    //   ctx.beginPath()
    //   ctx.lineWidth = lineWidth
    //   ctx.strokeStyle = '#7775FD'
    //   ctx.arc(x, y, r, 0, Math.PI * 2, false)
    //   ctx.fillStyle = fillColor
    //   // 填充当前的图像（路径）。默认颜色是黑色
    //   ctx.fill()
    //   ctx.stroke()
    //   ctx.restore()
    // }

    /**
     * 画三角形
     * @param angle {number}  弧度所对应的角度
     */
    // const triangle = (angle: any) => {
    //   const ctx = state.ctx
    //   ctx.save()
    //   ctx.beginPath()
    //   ctx.lineWidth = 1
    //   const rad = (angle * Math.PI) / 180
    //   const startX = state.circleX - Math.cos(rad) * 40
    //   const startY = state.circleY - Math.sin(rad) * 40
    //   ctx.moveTo(startX, startY)
    //   const rad1 = ((90 - angle) * Math.PI) / 180
    //   const startX1 = state.circleX - Math.cos(rad1) * 11
    //   const startY1 = state.circleY + Math.sin(rad1) * 11
    //   ctx.lineTo(startX1, startY1)
    //   const rad2 = ((90 - angle) * Math.PI) / 180
    //   const startX2 = state.circleX + Math.cos(rad2) * 11
    //   const startY2 = state.circleY - Math.sin(rad2) * 11
    //   ctx.lineTo(startX2, startY2)
    //   ctx.closePath()
    //   ctx.fillStyle = '#8382FF'
    //   ctx.fill()
    //   ctx.strokeStyle = '#8382FF'
    //   ctx.stroke()
    //   ctx.restore()
    // }

    /**
     * 绘制图形
     * @param angle {number}  角度
     */
    const draw = (angle?: any) => {
      const ctx = state.ctx
      const width = ctx.canvas.width
      // const height = ctx.canvas.height
      const borderWidth = props.borderWidth
      const borderColor = props.borderColor
      const lightBorderColor = props.lightborderColor
      const radius = width / 2 - borderWidth / 2

      // const textColor = '#3A85FF'
      // const textSize = 36
      const dashStart = radius - props.borderWidth
      const dashend = radius - props.borderWidth - props.dashWidth

      state.ctx.clearRect(0, 0, state.circleX * 2, state.circleY * 2)

      // circle(120, 8, "#F8F8F8");
      // circle(100, 2, "#BBBAFF");
      circle(radius, borderWidth, lightBorderColor, 360)
      // circle(50, 2, "#F8F8F8");
      // circle(30, 2, "#F8F8F8");
      // scale(0, 13, 65, 62, "#F2F2F2");
      if (props.showDashed) {
        scale(0, 24, dashStart, dashend, props.scaleColor)
      }
      if (props.showDashed) {
        scale(0.5, 24, dashStart, dashend, props.scaleColor)
      }
      // fillText("正常", 40, 150);
      // fillText("警告", 200, 10);
      // fillText("高危", 360, 150);
      // fillText("风险项", width / 2, height / 2 + 20, "#9A9A9A", "16");
      // fillText('98', width / 2, height / 2, textColor, textSize);
      // fillText("企业经营正常，风险系数低", 200, 200, "#62C513", "12");
      // round(100, 150, 4);
      // round(200, 50, 4);
      // round(300, 150, 4);
      // round(200, 150, 10, "#8382FF", 1);
      if (angle > 0) {
        circle(radius, borderWidth, borderColor, angle)
      }
      // triangle(angle);
      // round(200, 150, 4);
    }

    const {count, countStart} = useEaseInOut({startVal: 0, endVal: props.range})

    watch(
      () => count.value,
      n => {
        if (state.ctx) {
          // 当count变换时，画出仪表图
          draw(n)
        }
      }
    )

    watch(
      () => props.id,
      n => {
        if (n) {
          nextTick(() => {
            const canvas = document.getElementById(props.id) as HTMLCanvasElement
            if (!canvas) {
              return
            }
            state.ctx = canvas.getContext('2d')
            state.circleX = canvas.width / 2 // 中心x坐标
            state.circleY = canvas.height / 2 //中心y坐标
            state.range = deepClone(props.range)
            // 开始加载效果
            countStart({startVal: 0, endVal: state.range})
          })
        }
      },
      {immediate: true}
    )

    return () => (
      <div class='relative'>
        <a-tooltip placement='top' title={props.tooltipTitle}>
          {/*  transform rotate-90 */}
          <canvas
            class='inline-block transform rotate-90'
            id={props.id}
            width={props.radius * 2}
            height={props.radius * 2}
          ></canvas>
          <div
            class='absolute transform -translate-x-1/2 -translate-y-1/2  text-primaryHalf'
            style={{
              top: props.radius + 'px',
              left: props.radius + 'px'
            }}
          >
            {slots.default?.()}
          </div>
        </a-tooltip>
      </div>
    )
  }
})

export const WaterTargetEchart = defineComponent({
  props: {
    canvasId: {
      type: String,
      required: true
    },
    width: {type: String, required: true},
    height: {type: String, required: true},
    colors: {
      type: Array as PropType<string[]>,
      default: () => ['#50ce82', '#f25656', '#f9b641', '#909399']
    },
    seriesData: {
      type: Array as PropType<{value: number; name: string}[]>,
      default: () => []
    },
    tooltipTitle: String,
    tooltipValueUnit: String
  },
  setup(props, {emit}) {
    console.log(props.seriesData)

    const state = reactive<ECOption>({
      color: props.colors,
      tooltip: {
        trigger: 'item',
        className: 'tooltipBox',
        formatter: (params: any) => {
          return coustomEchartTooltip(params, {
            contentLeftText: params.name,
            contentTitle: props.tooltipTitle,
            contentValueUnit: props.tooltipValueUnit
          })
        }
      },
      series: [
        {
          name: '水质分析',
          type: 'pie',
          radius: '90%',
          label: {
            show: false,
            position: 'center',
            fontWeight: 'bold',
            fontSize: '16',
            fontFamily: 'Source Han Sans CN-Bold, Source Han Sans CN',
            formatter: params => {
              return params.percent + '%'
            }
          },
          emphasis: {
            focus: 'self',
            label: {
              show: false,
              backgroundColor: '#fff',
              fontWeight: 'bold',
              fontSize: '16',
              fontFamily: 'Source Han Sans CN-Bold, Source Han Sans CN'
            }
          },
          data: props.seriesData
        }
      ]
    })

    watch(
      () => props.seriesData,
      n => {
        getEchartOption()
      }
    )

    onMounted(() => {
      getEchartOption()
    })

    function getEchartOption() {}
    return () =>
      props.seriesData ? (
        <CEcharts
          id={props.canvasId}
          width={props.width}
          height={props.height}
          option={state as ECOption}
        ></CEcharts>
      ) : null
  }
})

export const WaterTargetScreen = defineComponent({
  name: 'WaterTargetScreen',
  props: {
    id: {
      type: String,
      required: true
    },
    radius: {
      type: Number,
      default: 61
    },
    borderColor: {
      type: [String, Array] as PropType<string | string[]>,
      default: '#3A85FF'
    },
    borderWidth: {
      type: Number,
      default: 8
    },
    lightborderColor: {
      type: [String, Array] as PropType<string | string[]>,
      default: '#D6E9FF'
    },
    dashWidth: {
      type: Number,
      default: 4
    },
    fontSize: {
      type: Number,
      default: 36
    },
    fontColor: {
      type: String,
      default: '#3A85FF'
    },
    range: {
      type: Number,
      required: true
    },
    tooltipTitle: String
  },
  setup(this, props, {slots}) {
    const state = reactive<{[key: string]: any}>({
      ctx: null,
      circleX: null,
      circleY: null,
      angle: 0
    })

    const {count} = useEaseInOut({startVal: 0, endVal: props.range})

    /**
     * 画圆环
     * @param r {number} 圆环的半径
     * @param w {number} 圆环的宽度
     * @param c {string} 圆环的颜色
     * @param angle {string} 圆环所到的角度 默认180度，半圆
     */
    const circle = (r: any, w: any, c: string | string[], angle: any = 180) => {
      const ctx = state.ctx
      // 画布将当前的状态保存
      // canvas.save();与canvas.restore();一般结合使用，.save()函数在前，.restore()函数在后，
      // 用来保证在这两个函数之间所做的操作不会对原来在canvas上所画图形产生影响
      ctx.save()
      // 开始一条路径，或重置当前的路径
      ctx.beginPath()
      // 设置线条的宽度
      ctx.lineWidth = w

      if (Array.isArray(c)) {
        const con = r * 2
        const grd = ctx.createLinearGradient(con, con, con, 0)
        grd.addColorStop(0, c[1])
        grd.addColorStop(1, c[0])
        // 设置线条的颜色
        ctx.strokeStyle = grd
      } else {
        ctx.strokeStyle = c
      }

      // 线条末端线帽的设置为圆形
      ctx.lineCap = 'round'
      // 方法创建弧/曲线（用于创建圆或部分圆）
      ctx.arc(state.circleX, state.circleY, r, Math.PI, Math.PI * (1 + angle / 180))
      ctx.stroke()
      // 画布取出原来所保存的状态
      ctx.restore()
    }

    /**
     * 绘制圆
     * @param x {number} 圆心的x坐标轴
     * @param y {number} 圆心的y坐标轴
     * @param r {number} 圆的半径
     * @param fillColor {string} 圆所填充的颜色
     * @param lineWidth {number} 圆的宽度
     */
    const round = (r: any, fillColor = '#fff', lineWidth: number) => {
      const ctx = state.ctx
      ctx.save()
      ctx.beginPath()
      ctx.lineWidth = lineWidth
      ctx.strokeStyle = fillColor
      ctx.arc(state.circleX, state.circleY, r, 0, Math.PI * 2, false)
      ctx.fillStyle = fillColor
      // 填充当前的图像（路径）。默认颜色是黑色
      ctx.fill()
      ctx.stroke()
      ctx.restore()
    }

    /**
     * 绘制图形
     * @param angle {number}  角度
     */
    const draw = (angle?: any) => {
      const ctx = state.ctx
      const width = ctx.canvas.width
      // const height = ctx.canvas.height
      const borderWidth = props.borderWidth
      const borderColor = props.borderColor
      // const lightBorderColor = props.lightborderColor
      const radius = width / 2 - borderWidth / 2
      state.ctx.clearRect(0, 0, state.circleX * 2, state.circleY * 2)

      round(radius, '#e8f8ff', 0)

      if (angle > 0) {
        circle(radius, borderWidth, borderColor, angle)
      }
    }

    watch(
      () => count.value,
      n => {
        draw(n)
      }
    )

    onMounted(() => {
      const canvas = document.getElementById(props.id) as HTMLCanvasElement
      if (!canvas) {
        return
      }
      state.ctx = canvas.getContext('2d')
      state.circleX = canvas.width / 2 // 中心x坐标
      state.circleY = canvas.height / 2 //中心y坐标
      state.range = deepClone(props.range)
      draw()
    })

    return () => (
      <div class='relative'>
        <a-tooltip class='' placement='top' title={props.tooltipTitle}>
          {/*  transform rotate-90 */}
          <canvas
            class='inline-block transform rotate-90'
            id={props.id}
            width={props.radius * 2}
            height={props.radius * 2}
          ></canvas>
          <div
            class='absolute transform -translate-x-1/2 -translate-y-1/2  text-primaryHalf'
            style={{
              top: props.radius + 'px',
              left: props.radius + 'px'
            }}
          >
            {slots.default?.()}
          </div>
        </a-tooltip>
      </div>
    )
  }
})

export default WaterTarget

/**暂时有缺点 */
export const WaterTargetCanvas = defineComponent({
  props: {
    value: {
      type: Number,
      default: 0
    },
    max: {
      type: Number,
      default: 100
    }
  },
  setup(props, ctx) {
    const strokeDasharray = ref('0')

    watch(
      () => props.value,
      newVal => {
        strokeDasharray.value = (newVal / props.max) * 100 + ', 100'
      },
      {immediate: true}
    )

    return () => (
      <div class='w-100 h-100'>
        <svg viewBox='0 0 100 100' width='100' height='100'>
          <circle cx='50' cy='50' r='45' stroke-width='5' stroke='black' fill='transparent' />
          <circle
            cx='50'
            cy='50'
            r='45'
            stroke-width='5'
            stroke='green'
            fill='transparent'
            stroke-dasharray={strokeDasharray.value}
          />
          <text x='50' y='50' fill='black' text-anchor='middle' alignment-baseline='middle'>
            {props.value}
          </text>
        </svg>
      </div>
    )
  }
})
